
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Command_Line;      use Ada.Command_Line;

-- https://leetcode.com/problems/zigzag-conversion/
procedure leet6_zigzag is
    function strip (s : in string) return unbounded_string is
        t : unbounded_string;
    begin 
        for char of s loop
            if char /= character'val(0) then
                append(t, char);
            end if;
        end loop;
        return t;
    end strip;

    function zigzag(s : in String; rows : in Integer) return Unbounded_string is
        x : Integer := 0;
        y : Integer := 0;
        zig : boolean := True; -- true for vertical, false for diagonal
        i : Integer := 0;      -- index based on (x,y)
        -- how many odd numbers are in s'length
        -- e.g 13 => 1, 3, 5, 7, 9, 11, 13 => columns =  7
        -- great place to have a ternary operator
        columns : constant Integer  := (s'length/2) + 1; -- rounded up
        upper   : constant positive := rows * columns;
        output  : string(1..upper)  := (others => character'val(0));
    begin
        for char of s loop
            -- calculate index for output from (x, y)
            i := columns * y + x;
            output(i+1) := char;
--            put(char & " @");
--            put("(" & integer'image(x) & ", " & integer'image(y) & ")");
--            put_line(" => " & integer'image(i));

            -- calculate next position (x, y)
            if zig then -- go straight down
                y := y + 1;
                if y = (rows - 1) then
                    zig := False;
                end if;
            else        -- go diagonaly up
                x := x + 1;
                y := y - 1;
                if y = 0 then
                    zig := True;
                end if;
            end if;
        end loop;
        return strip(output);
    end zigzag;

    procedure main is
        input  : String  := argument(1);
        rows   : Integer := Integer'value(argument(2));
        output : unbounded_string;
    begin
        output := zigzag(input, rows);
        put_line(to_string(output));
    end main;

begin
    if argument_count < 1 then
        put_line("This is leetcode algorithm challenge #6 - Zigzag Conversion");
        put_line("usage: <program name> <string> <rows>");
        return;
    end if;
    main;
end leet6_zigzag;
